package com.ruoyi.xag.controller;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.lightkillPest.domain.device.SCDDeviceDao;
import com.ruoyi.permission.Dao.SerDevicePermi;
import com.ruoyi.permission.domain.BaseBlockPermiDeviceInfo;
import com.ruoyi.permission.domain.BlockPermiDeviceInfo;
import com.ruoyi.permission.mapper.SerDevicePermiMapper;
import com.ruoyi.permission.mapper.SerUnitUserMapper;
import com.ruoyi.permission.service.PermiService;
import com.ruoyi.utils.LocationUtil;
import com.ruoyi.xag.domain.IotDeviceInfo;
import com.ruoyi.xag.domain.SoilData;
import com.ruoyi.xag.domain.WeatherData;
import com.ruoyi.xag.domain.WeatherDataAndGDD;
import com.ruoyi.xag.domain.datapoints.SoilSenorDataPoints;
import com.ruoyi.xag.domain.datapoints.WeatherSenorDataPoints;
import com.ruoyi.xag.domain.iotdevice.IotDevice;
import com.ruoyi.xag.service.DataService;
import com.ruoyi.xag.service.DeviceService;
import com.ruoyi.xag.service.SessionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author LiSuxuan 2
 * @date 2021年 06月 22日 15:02
 */
@Api("物联网设备控制类")
@Slf4j
@RestController
@RequestMapping("/iot")
public class IotController extends BaseController {

    @Autowired
    private SessionService sessionService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private DataService dataService;

    @Autowired
    private SerDevicePermiMapper devicePermiMapper;

    @Autowired
    private PermiService permiService;

    @Autowired
    SerUnitUserMapper unitUserMapper;

    /**
     * 查询列表
     * @return 设备列表
     */
    @ApiOperation("获取账户下所有物联网设备列表")
    @GetMapping("/list")
    public AjaxResult list() {
        List<IotDevice> iotDevices;
        try {
            iotDevices = deviceService.selectDeviceList();
        } catch (IOException | ParseException e) {
            e.printStackTrace();
            return AjaxResult.error("查询列表出错，请检查!");
        }
        return AjaxResult.success(iotDevices);
    }

    /**
     * 获取IOT传感器最近一条数据并保存
     *
     * @return
     */
    @ApiOperation("后端测试接口，请忽略！")
    @GetMapping("/dataLast")
    public AjaxResult dataPointsLast(String weatherId,String soilId) {
//        if(weatherId.equals("")){
//            weatherId = "W863320045453949";
//        }
//        if(soilId.equals("")){
//            soilId = "W863320045456603";
//        }
        System.out.println(weatherId);
        System.out.println(soilId);
        try {
            int weather = 0;
            int soil = 0;
            IotDevice weatherDevice = deviceService.selectDeviceInfo(weatherId);
            IotDevice soilDevice = deviceService.selectDeviceInfo(soilId);
            // 判断设备是否在线 0:未激活，1:在线，2:离线
            if (weatherDevice.getStatus() == 1) {
                weather = deviceService.insertWeatherDataPointLast(weatherId);
            }
            if (soilDevice.getStatus() == 1) {
                soil = deviceService.insertSoilDataPointLast(soilId);
            }
            // 根据返回值判断影响行数，决定是否获取数据成功
            return (weather > 0 && soil > 0) ? AjaxResult.success("获取成功") : AjaxResult.error("获取最近一条数据失败!" + "weather status:" + weatherDevice.getStatus() + "; soil status:" + soilDevice.getStatus());
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error("获取失败！");
        }
    }

    /**
     * 获取气象传感器的历史数据
     *
     * @param deviceId 设备ID
     * @param start    开始时间
     * @param end      截止时间
     * @return 返回数据列表
     */
    @GetMapping("/weatherDetail")
    @ApiOperation("获取气象传感器的历史数据,start：开始时间，end：结束时间，两个时间都为unix时间(秒)，例如:http://localhost:8080/iot/weatherDetail?deviceId=W866323036668209&start=1616362100&end=1618362900a")
    public AjaxResult weatherHistoryData(String deviceId, int start, int end) {
        List<WeatherSenorDataPoints> weatherSenorDataPoints = deviceService.selectWeatherHistoryData(deviceId, start, end);
        if (weatherSenorDataPoints.size() != 0) {
            return AjaxResult.success(weatherSenorDataPoints);
        } else {
            return AjaxResult.error("输入参数格式错误或者此时间段内无数据！");
        }
    }

    /**
     * 获取土壤传感器的历史数据
     *
     * @param deviceId 设备Id
     * @param start    开始时间
     * @param end      截止时间
     * @return 返回数据列表
     */
    @GetMapping("/soilDetail")
    @ApiOperation("获取土壤传感器的历史数据,start：开始时间，end：结束时间，两个时间都为unix时间(秒)，例如:http://localhost:8080/iot/soilDetail?deviceId=W866323036380573&start=1616362100&end=1618362900")
    public AjaxResult soilHistoryData(String deviceId, int start, int end) {
        List<SoilSenorDataPoints> soilSenorDataPoints = deviceService.selectSoilHistoryData(deviceId, start, end);
        if (soilSenorDataPoints.size() != 0) {
            return AjaxResult.success(soilSenorDataPoints);
        } else {
            return AjaxResult.error("输入参数格式错误或者此时间段内无数据！");
        }
    }
    /**
     * 获取气象传感器的历史数据2
     *
     * @param deviceId 设备ID
     * @param start    开始时间
     * @param end      截止时间
     * @return 返回数据列表
     */
    @GetMapping("/weatherHis")
    public AjaxResult weatherHistoryData2(String deviceId, String start, String end) {
        List<WeatherSenorDataPoints> weatherSenorDataPoints = deviceService.selectWeatherHistoryData2(deviceId, start, end);
        if (weatherSenorDataPoints.size() != 0) {
            return AjaxResult.success(weatherSenorDataPoints);
        } else {
            return AjaxResult.error("输入参数格式错误或者此时间段内无数据！");
        }
    }

    /**
     * 获取土壤传感器的历史数据2
     *
     * @param deviceId 设备Id
     * @param start    开始时间
     * @param end      截止时间
     * @return 返回数据列表
     */
    @GetMapping("/soilDHis")
    public AjaxResult soilHistoryData2(String deviceId, String start, String end) {
        List<SoilSenorDataPoints> soilSenorDataPoints = deviceService.selectSoilHistoryData2(deviceId, start, end);
        if (soilSenorDataPoints.size() != 0) {
            return AjaxResult.success(soilSenorDataPoints);
        } else {
            return AjaxResult.error("输入参数格式错误或者此时间段内无数据！");
        }
    }

    /**
     * 查询一条数据，用于首页展示
     *
     * @param deviceId 设备唯一ID
     * @return 查询结果
     */
    @ApiOperation("获取气象传感器数据最近一次数据，用于首页展示接口，例如：http://localhost:8080/iot/oneWeather?deviceId=W866323036668209")
    @GetMapping("/oneWeather")
    public AjaxResult getWeatherDataLast(String deviceId) {
        WeatherSenorDataPoints weatherSenorDataPoints = deviceService.selectWeatherDataLast(deviceId);
        return weatherSenorDataPoints == null ? AjaxResult.error("出错，联系管理人员") : AjaxResult.success(weatherSenorDataPoints);
    }

    /**
     * 查询一条数据，用于首页展示
     *
     * @param deviceId 设备唯一ID
     * @return 查询结果
     */
    @ApiOperation("获取土壤传感器数据最近一次数据，用于首页展示接口，例如：http://localhost:8080/iot/oneSoil?deviceId=W866323036380573")
    @GetMapping("/oneSoil")
    public AjaxResult getSoilDataLast(String deviceId) {
        SoilSenorDataPoints soilSenorDataPoints = deviceService.selectSoilDataLast(deviceId);
        return soilSenorDataPoints == null ? AjaxResult.error("出错，联系管理人员") : AjaxResult.success(soilSenorDataPoints);
    }

    /**
     * 根据设备ID获取气象传感器历史数据中每天的最大最小值
     *
     * @param deviceId  设备ID
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 列表
     */
    @GetMapping("/weather")
    @ApiOperation("根据设备ID获取气象传感器历史数据中每天的最大、最小、平均值，例如：http://localhost:8080/iot/weather?deviceId=W866323036668209&startTime=2021-07-01&endTime=2021-07-08")
    public AjaxResult weatherHistoryDataMaxMinValue(String deviceId, String startTime, String endTime) {
//        积温
        Float GDD = 0f;
        List<WeatherData> weatherDataList = dataService.weatherDataStatistics(deviceId, startTime, endTime);

        if (weatherDataList.size() != 0) {
            for(WeatherData weatherData:weatherDataList){
                if(weatherData.getTemperatureAverage()!=null) {
//                有效积温 = ∑（平均气温-水稻生物学零度（10））
                    GDD += weatherData.getTemperatureAverage() - 10;
                }
            }
            WeatherDataAndGDD weatherDataAndGDD = new WeatherDataAndGDD().setWeatherDataList(weatherDataList).setGDD(GDD);
            return AjaxResult.success(weatherDataAndGDD);
        } else {
            return AjaxResult.error("输入参数格式错误或者此时间段内无数据！");
        }
    }

    /**
     * 根据设备ID获取土壤传感器历史数据中每天的最大最小值
     *
     * @param deviceId  设备ID
     * @param startTime 开始时间
     * @param endTime   结束时间
     */
    @GetMapping("/soil")
    @ApiOperation("根据设备ID获取土壤传感器历史数据中每天的最大、最小、平均值，例如：http://localhost:8080/iot/soil?deviceId=W866323036380573&startTime=2021-07-01&endTime=2021-07-09")
    public AjaxResult soilHistoryDataMaxMinAveValue(String deviceId, String startTime, String endTime) {
        List<SoilData> soilDataList = dataService.soilDataStatistics(deviceId, startTime, endTime);
        if (soilDataList.size() != 0) {
            return AjaxResult.success(soilDataList);
        } else {
            return AjaxResult.error("输入参数格式错误或者此时间段内无数据！");
        }
    }


//    @GetMapping("weatherHistory")
//    public AjaxResult xagWeatherHistoryStatistics(String deviceId, int start, int end) throws IOException {
//        String historyMaxMinAve = dataService.weatherHistoryMaxMinAve(deviceId, start, end);
//        return AjaxResult.success(historyMaxMinAve);
//    }

    /**
     * 查询该账号下的所有设备
     * @return
     */
    @GetMapping("/getAllIotDeviceInfo")
    public AjaxResult getAllIotDevice(){
        Long userIdL = SecurityUtils.getLoginUser().getUser().getUserId();
        Integer userId=Integer.valueOf(userIdL.intValue());
        Integer unitId = 0;
        if(userId != 1 && userId != 20) {
            unitId = unitUserMapper.selectByPrimaryKey(userId).getUnitId();
        }
        //管理员则返回所有设备
        if(unitId == 0) {
            List<IotDeviceInfo> lst = deviceService.selectAllIotDevice();
            return AjaxResult.success(lst);
        }else {
            //获取单位下所有设备
            List<BaseBlockPermiDeviceInfo> baseBlockPermiDeviceInfoList = permiService.selectAllDeviceByUnitId(unitId);
            List<SerDevicePermi> SCDDevicePermiList = new ArrayList<>();
            for (BaseBlockPermiDeviceInfo baseBlockPermiDeviceInfo : baseBlockPermiDeviceInfoList) {
                if (baseBlockPermiDeviceInfo.getTypeId() == 3 ||baseBlockPermiDeviceInfo.getTypeId() == 4) {
                    SerDevicePermi serDevicePermi = new SerDevicePermi().setDeviceName(baseBlockPermiDeviceInfo.getDeviceName()).setDeviceNo(baseBlockPermiDeviceInfo.getDeviceId())
                            .setDeviceType(baseBlockPermiDeviceInfo.getDeviceType()).setDeviceSerial(baseBlockPermiDeviceInfo.getDeviceSerial()).setId(baseBlockPermiDeviceInfo.getId());
                    SCDDevicePermiList.add(serDevicePermi);
                }
            }
            List<IotDeviceInfo> iotDeviceInfoList = deviceService.selectIotDeviceByCondition(SCDDevicePermiList);
            return AjaxResult.success(iotDeviceInfoList);
        }

    }

    /**
     * 修改设备别名
     * @param info
     * @return
     */
    @PostMapping("/modifyDeviceNickName")
    public AjaxResult modifyNickName(IotDeviceInfo info){
        if (info.getDeviceId()==null||info.getDeviceId().equals("")){
            return AjaxResult.error("修改的设备序列号不能为空！");
        }else{
            int res = deviceService.updateDeviceNickName(info);
            String deviceSerial = info.getDeviceId();
            if(devicePermiMapper.selectByDeviceSerial(deviceSerial)!=null) {
                SerDevicePermi devicePermiInfo = devicePermiMapper.selectByDeviceSerial(deviceSerial);
                devicePermiInfo.setDeviceName(info.getDeviceName());
                devicePermiInfo.setDeviceSerial(info.getDeviceId());
                devicePermiMapper.updateByPrimaryKeySelective(devicePermiInfo);
            }
            if(res==1){
                return AjaxResult.success("修改成功！");
            }else{
                return AjaxResult.error("修改失败！");
            }
        }
    }
    /**
     * 更新设备地区信息
     * @param iotDeviceInfo
     * @return
     * @throws IOException
     */
    @PostMapping("/updateIotDeviceInfo")
    public AjaxResult updateIotDeviceInfo(IotDeviceInfo iotDeviceInfo) throws IOException {
        if(iotDeviceInfo.getLocation()!=null && iotDeviceInfo.getLocation()!=""){
            double[] location = LocationUtil.geocode(iotDeviceInfo.getLocation());
            Double longitudeFinal = location[0];
            Double latitudeFinal = location[1];
            iotDeviceInfo.setLongitude(longitudeFinal);
            iotDeviceInfo.setLatitude(latitudeFinal);
            JSONObject locationObject = LocationUtil.reverseGeoCode(longitudeFinal,latitudeFinal);
            //详细地址，用于更新各个表中的地址
//            String locationStr = locationObject.getString("formattedAddress");
            String area = locationObject.getString("city") + locationObject.getString("district");
            String province = locationObject.getString("province");
            if(devicePermiMapper.selectByDeviceSerial(iotDeviceInfo.getDeviceId()) != null){
                SerDevicePermi devicePermiInfo = devicePermiMapper.selectByDeviceSerial(iotDeviceInfo.getDeviceId());
                devicePermiInfo.setArea(area);
                devicePermiInfo.setProvince(province);
                devicePermiInfo.setLongitude(longitudeFinal);
                devicePermiInfo.setLatitude(latitudeFinal);
                devicePermiMapper.updateByPrimaryKeySelective(devicePermiInfo);
//                if(j > 0){
//                    return AjaxResult.success("更新权限设备的地区信息成功");
//                }else {
//                    return AjaxResult.error("更新权限设备的地区信息失败");
//                }
            }

        }
        int i = deviceService.updateDeviceInfo(iotDeviceInfo);
        if(i>0){
            return AjaxResult.success("更新成功");
        }else{
            return AjaxResult.error("更新失败");
        }
    }
}
